package com.tom.joke.view.banner;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;

import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * Added by Tom on 2024/07/16.
 * 自定义广告位Banner。
 */
public class BannerViewPager extends ViewPager {
    private static final String TAG = "BannerViewPager";
    // 自定义BannerViewPager 的adapter。
    private BannerAdapter mAdapter;

    private static final int SCROLL_MSG = 0x0011; // 开始切换的消息
    private int mCutDownTime = 2500; // 切换间隔事件
    private BannerScroller mScroller; // 自定义页面切换的scroller。

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Log.e(TAG, "handleMessage");
            // 每隔几秒，切换到下一页。
            setCurrentItem(getCurrentItem() + 1);
            startRoll(); // 再次轮询
        }
    };

    // 内存优化：界面复用-复用的界面cell
    private List<View> mConvertViews;
    // 内存优化：当前Activity
    private Activity mActivity;

    public BannerViewPager(Context context) {
        this(context, null);
    }

    public BannerViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        mActivity = (Activity) context;
        try {
            // 3. 改变ViewPager切换的速率：改变duration持续时间。改变mScroller，通过反射获得它。
            Field field = ViewPager.class.getDeclaredField("mScroller");
            field.setAccessible(true);
            // 设置插值器。
            mScroller = new BannerScroller(context, new AccelerateInterpolator());
            // 参数1：object 当前属性在那个类
            // 参数2：要设置的值
            field.set(this, mScroller); // 设置参数,设置为自定义的。
        } catch (Exception e) {
            e.printStackTrace();
        }

        mConvertViews = new ArrayList<View>();
    }

    public void setAdapter(BannerAdapter adapter) {
        mAdapter = adapter;
        // 设置父类ViewPager的adapter。
        setAdapter(new BannerPagerAdapter());

        // 管理 Activity 的生命周期。
        mActivity.getApplication().registerActivityLifecycleCallbacks(mLifecycleCallbacks);
    }


    /**
     * 3.设置页面切换速率
     */
    public void setScrollerDuration(int scrollerDuration) {
        this.mScroller.setScrollDuration(scrollerDuration);
    }

    /**
     * 1.实现自动轮播
     */
    public void startRoll() {
        mHandler.removeMessages(SCROLL_MSG); // 清除之前的消息
        mHandler.sendEmptyMessageDelayed(SCROLL_MSG, mCutDownTime);
    }

    /**
     * 2.销毁handler，停止发送消息. 解决内存泄漏。
     */
    @Override
    protected void onDetachedFromWindow() {
        Log.e(TAG, "onDetachedFromWindow: ");
        // 销毁handler的生命周期。
        mHandler.removeMessages(SCROLL_MSG);
        mHandler = null;
        // 解除绑定，参考Glide图片加载。
        mActivity.getApplication().unregisterActivityLifecycleCallbacks(mLifecycleCallbacks);
        super.onDetachedFromWindow();
    }

    private class BannerPagerAdapter extends PagerAdapter {
        @Override
        public int getCount() {
            return Integer.MAX_VALUE; // 为了实现无线轮播
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            // 官方推荐这么写。
            return view == object;
        }

        // 创建item的回调方法
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // 采用Adapter模式，为了完全让用户去自定义。
            // position: 0~ 2的31次方
            int posInArray = position % mAdapter.getCount(); // [0, (size-1)]
            View bannerItemView = mAdapter.getView(posInArray, getConvertView());
            // 添加到ViewPager里面。
            container.addView(bannerItemView);
            bannerItemView.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View view) {
                    // 设置点击的回调。
                    if (mListener != null) {
                        mListener.click(posInArray);
                    }
                }
            });
            return bannerItemView;
        }

        // 销毁item的回调方法。销毁的时候，添加到复用列表。
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
            mConvertViews.add((View) object);  // list会一直增加，注意处理。
            Log.d("TAG", "size:" + mConvertViews.size());
        }
    }

    // 10.获取复用的界面，view
    private View getConvertView() {
        for (int i = 0; i < mConvertViews.size(); i++) {
            // 获取没被添加到ViewPager里面的。
            if (mConvertViews.get(i).getParent() == null) {
                // view 未被添加过，复用view. 避免mConvertViews一直增加。
                View convertView = mConvertViews.get(i);
                mConvertViews.remove(convertView);
                return convertView;
            }
        }
        return null;
    }


    private BannerItemClickListener mListener;
    public void setOnBannerItemClickListener(BannerItemClickListener listener) {
        this.mListener = listener;
    }
    // 10.点击回调监听
    public interface BannerItemClickListener {
        void click(int position);
    }

    // 11.管理Activity生命周期
    Application.ActivityLifecycleCallbacks mLifecycleCallbacks = new DefaultActivityLifecycleCallbacks() {
        @Override
        public void onActivityResumed(Activity activity) {
            // 是否监听的当前 Activity的生命周期。
            if (activity == mActivity) {
                // 重新开始轮播
                mHandler.sendEmptyMessageDelayed(mCutDownTime, SCROLL_MSG);
                Log.e(TAG, "重新开始轮播");
            }
        }
        @Override
        public void onActivityPaused(Activity activity) {
            if (activity == mActivity) {
                // 停止轮播
                mHandler.removeMessages(SCROLL_MSG);
                Log.e(TAG, "停止轮播");
            }
        }
    };

}
